package com.example.myapplication6;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;
import java.util.StringTokenizer;

public class MainActivity extends AppCompatActivity {
    Arithmetic math = new Arithmetic();
    String result = " ";
    String an=" ";
Comparision math1=new Comparision();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button botton1 = findViewById(R.id.button1);
        Button botton2 = findViewById(R.id.button2);
        Button botton3 = findViewById(R.id.button3);
        Button botton4 = findViewById(R.id.button4);
        final EditText editText_3 = findViewById(R.id.editText3);
        final EditText editText_4 = findViewById(R.id.editText4);
        final EditText editText_5 = findViewById(R.id.editText5);
       final EditText editText=findViewById(R.id.editText);

        botton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                editText_3.setText(math.level3());
                result = " ";

            }
        });
        botton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String infix = editText_3.getText().toString();
                String suffix;
                char[] operator = {'+', '-', '*', '÷'};
                Random generator = new Random();
                int num1, num2, num3, num4, a;
                String result = "";
                ArrayList<String> questionName = new ArrayList<>();


                //infix to suffix
                class Convert {
                    List<String> expre;   // expression 表达式
                    Stack<String> op;   // 操作符
                    String result = "";

                    public Convert() {
                        expre = new ArrayList<String>();
                        op = new Stack();
                    }

                    // 中缀表达式转后缀表达式的转换方法。
                    public String transit(String q)  // question
                    {
                        String a;           // a 是字符
                        StringTokenizer tokenizer = new StringTokenizer(q);

                        while (tokenizer.hasMoreTokens()) {
                            a = tokenizer.nextToken();

                            if (a.equals("("))
                            {op.push(a);
                            an+="运算式"+expre+"栈"+op+"\n";}// 如果是"("，入栈
                            else if (a.equals("+") || a.equals("-")) {
                                if (!op.isEmpty()) {
                                    if (op.peek().equals("("))
                                    {op.push(a);
                                    an+="运算式"+expre+"栈"+op+"\n";}// 如果栈顶"("，运算符入栈
                                    else {
                                        expre.add(op.pop());        // 先移除栈顶元素到列表中，再将运算符入栈
                                        op.push(a);
                                        an+="运算式"+expre+"栈"+op+"\n";
                                    }
                                } else {
                                    op.push(a);
                                    an+="运算式"+expre+"栈"+op+"\n"; // 栈为空，运算符入栈
                                }
                            } else if (a.equals("*") || a.equals("÷")) {
                                if (!op.isEmpty()) {
                                    if (op.peek().equals("*") || op.peek().equals("÷")) {
                                        expre.add(op.pop());
                                        op.push(a);
                                        an+="运算式"+expre+"栈"+op+"\n";
                                    } else
                                        op.push(a);
                                    an+="运算式"+expre+"栈"+op+"\n";
                                } else
                                    op.push(a);
                                an+="运算式"+expre+"栈"+op+"\n";// 如果栈为空，运算符入栈
                            } else if (a.equals(")")) {
                                while (true) {
                                    String b = op.pop();
                                    if (!b.equals("(")) {
                                        expre.add(b);
                                    } else {
                                        break;
                                    }
                                }
                            } else {
                                expre.add(a);  // 如果为操作数，入列表
                            }
                        }
                        while (!expre.isEmpty() && !op.isEmpty()) {
                            expre.add(op.pop());
                        }

                        for (String x : expre)
                            result += x + " ";
                        return result;
                    }
                }
                Convert convert = new Convert();
                suffix = convert.transit(infix);
                editText_4.setText(suffix);
            }

        });
    botton3.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
             editText_5.setText(math1.calculator(editText_4.getText().toString()));


        }
    });
    botton4.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            editText.setText(an);
        }
    });
    }



    //RationalNumber.java Author:Lewis/Loftus
//Represents one rational number with a numerator and denominator.
    public class RationalNumber implements Comparable
    {
        private int numerator,denominator;
        //Constructor:Sets up the rational number by ensuring a nozero denominator and making only the numerator signed.
        public RationalNumber(int numer, int denom)
        {
            if (denom==0)
                denom = 1;
            //Make the numerator "store" the sign
            if (denom<0)
            {
                numer=numer*-1;
                denom=denom*-1;
            }
            numerator= numer;
            denominator = denom;
            reduce();
        }
        //Return the numerator of this rational number.
        public int getNumerator()
        {
            return numerator;
        }
        //Returns the denominator of this rational number.
        public int getDenominator()
        {
            return denominator;
        }
        //Returns the reciprocal of this rational number.
        public RationalNumber reciprocal()
        {
            return new RationalNumber(denominator,numerator);
        }
        //Adds this rational number to the one passed as a parameter.A common denominator is found by multiplying the indiviaual denominators.
        public RationalNumber add(RationalNumber op2)
        {
            int commonDenominator = denominator *op2.getDenominator();
            int numerator1 = numerator*op2.getDenominator();
            int numerator2 = op2.getNumerator()*denominator;
            int sum = numerator1 + numerator2;

            return new RationalNumber(sum,commonDenominator);
        }
        //Subtracts the rational number passed as a parmeter from this rational number.
        public RationalNumber subtract(RationalNumber op2)
        {
            int commonDenominator = denominator*op2.getDenominator();
            int numerator1 = numerator*op2.getDenominator();
            int numerator2 = op2.getNumerator()*denominator;
            int difference = numerator1-numerator2;

            return new RationalNumber(difference,commonDenominator);
        }
        //Mulitiplies this rational number by the one passed as a parameter.
        public RationalNumber multiply(RationalNumber op2)
        {
            int numer = numerator*op2.getNumerator();
            int denom = denominator*op2.getDenominator();

            return new RationalNumber(numer,denom);
        }
        //Divides this rational numer by the one passed as a parameter by multiplying by the reciorocal of the second rational.
        public RationalNumber divide(RationalNumber op2)
        {
            return multiply(op2.reciprocal());
        }
        //Determines if  this rational number is equal to the one passed as a parameter .Assumes
        //they are both reduced.
        public boolean isLike(RationalNumber op2)
        {
            return(numerator == op2.getNumerator() && denominator == op2.getDenominator());
        }
        //Returns this rational number as a string.
        public String toString()
        {
            String result;
            if (numerator == 0)
                result = "0";
            else
            if(denominator == 1)
                result = numerator+"";
            else
                result = numerator + "/"+denominator;
            return result;
        }
        //Reduces this rational number by dividing both the numerator and the denominator by their greatest common divisor.
        public void reduce()
        {
            if (numerator != 0)
            {
                int common = gcd(Math.abs(numerator),denominator);

                numerator = numerator/common;
                denominator = denominator/common;
            }
        }
        //Computes and returns the greatest common divisor of two positive parameters.
        //uses Euclid's algorithm.
        private int gcd(int num1,int num2)
        {
            while (num1 !=num2)
                if (num1 > num2)
                    num1= num1-num2;
                else
                    num2 =num2-num1;

            return num1;
        }
        //Comparing two rational numbers with error accuracy of 0.0001.
        public int compareTo(Object obj)
        {
            float a ;
            RationalNumber op2 = (RationalNumber)obj;
            RationalNumber temp = this.subtract(op2);
            a =(float)(temp.getNumerator()/temp.getDenominator());

            if (a>0){
                if(a<=0.0001)
                    return 0;
                else
                    return 1;
            }else
            if(a<0){
                if(a>=-0.0001)
                    return 0;
                else
                    return -1;
            }else
                return 0;
        }
    }

    public class Arithmetic {


        char[] operator = {'+', '-', '*', '÷'};
        Random generator = new Random();
        int num1, num2, num3, num4, num5, a;

        ArrayList<String> questionName = new ArrayList<>();

        //  输出1级题目：+、-
        public String level3() {
            num1 = generator.nextInt(20) + 1;
            num2 = generator.nextInt(20) + 1;
            num3 = generator.nextInt(4);
            int num6 = generator.nextInt(2) + 3;
            a = generator.nextInt(3);
            for (int aa = 0; aa < num6; aa++) {
                num4 = generator.nextInt(20) + 1;
                num5 = generator.nextInt(4);
                result += " " + num4 + " " + operator[num5] + " ";


            }
            result += num2;

            return result;
        }


    }



    // 后缀表达式求值
    public class Comparision {
        Stack<String> stack = new Stack<String>();

        RationalNumber num1,num2,num3;

        public Comparision() {
            stack = new Stack<String>();
        }

        public String calculator(String q)
        {
            String op1, op2, result;
            String a;
            StringTokenizer tokenizer = new StringTokenizer(q);

            while (tokenizer.hasMoreTokens())
            {
                a = tokenizer.nextToken();

                if(a.equals("+") || a.equals("-") || a.equals("*") || a.equals("÷"))
                {
                    // 把栈顶的操作数弹出，转换为RationalNumber类型
                    op2 = stack.pop();
                    num2 = conToRantionalNum(op2);

                    // 继续把栈顶的操作数弹出，转换为RationalNumber类型
                    op1 = stack.pop();
                    num1 = conToRantionalNum(op1);

                    //计算结果
                    result = calculate(num1,a.charAt(0),num2);
                    stack.push(result.toString());
                }
                else
                    stack.push(a);
            }
            result = stack.pop();
            return result;
        }

        public RationalNumber conToRantionalNum (String a)
        {
            String numer,denom;  // numer分子，denom分母


            //  把分数a/b以"/"为标记分割开
            StringTokenizer tokenizer1 = new StringTokenizer(a,"/");
            numer = tokenizer1.nextToken();
            if (tokenizer1.hasMoreTokens())
            //  如果分母不为1
            {
                denom = tokenizer1.nextToken();
                num1 = new RationalNumber(Integer.parseInt(numer), Integer.parseInt(denom));
            }
            else
            //  如果分母为1
            {
                num1 = new RationalNumber(Integer.parseInt(numer), 1);
            }
            return num1;
        }

        // 计算+、-、*、÷
        public String calculate(RationalNumber op1, char operation, RationalNumber op2)
        {
            RationalNumber result = new RationalNumber(0,1);

            switch (operation)
            {
                case '+':
                    result = op1.add(op2);
                    break;
                case '-':
                    result = op1.subtract(op2);
                    break;
                case '*':
                    result = op1.multiply(op2);
                    break;
                case '÷':
                    result = op1.divide(op2);
                    break;
            }
            return result.toString();
        }
    }





}


